import numpy as np 
import json
import pandas as pd   
import random, csv
from random import choice


'''
距离混淆矩阵

'''
distance = {'下渚湖国家湿地':[0,20.8,18.7,21.6,24.9,29.8,26.2,27.6,28.2,26,31.4,34.3,29],
            '东明山森林公园':[20.8,0,36.9,39.2,42.4,47.3,43.1,45.1,45.7,43.4,48.5,51.4,45.4],
            '蚕乐谷':[18.7,36.9,0,2.7,6,10.9,7.3,8.7,9.3,7,9.3,13.7,42.9],
            '庾村':[21.6,39.2,2.7,0,3.5,8.4,4.8,6.2,6.8,5.8,8,12.5,45.3],
            '旭光台':[24.9,42.4,6,3.5,0,1.1,1.3,2.7,3.7,9.1,11.3,13.7,48.8],
            '松月庐':[29.8,47.3,10.9,8.4,1.1,0,1.5,2.8,2.6,13.9,16.2,14.3,53.6],
            '芦花荡公园':[26.2,43.1,7.3,4.8,1.3,1.5,0,1.4,4.1,10.4,12.7,12.1,50.1],
            '剑池':[27.6,45.1,8.7,6.2,2.7,2.8,1.4,0,5.4,11.7,19.7,22,51.4],
            '莫干山大坑景区':[28.2,45.7,9.3,6.8,3.7,2.6,4.1,5.4,0,12.4,14.7,16.1,52.1],
            '裸心堡':[26,43.4,7,5.8,9.1,13.9,10.4,11.7,12.4,0,2.3,10,57.2],
            '三九坞':[31.4,48.5,9.3,8,11.3,16.2,12.7,19.7,14.7,2.3,0,12.3,55.2],
            '德清后坞村景区':[34.3,51.4,13.7,12.5,13.7,14.3,12.1,22,16.1,10,12.3,0,58.2],
            '新市古镇':[29,45.4,42.9,45.3,48.8,53.6,50.1,51.4,52.1,57.2,55.2,58.2,0]
           }

acrange = {'1':10,'2':30,'3':40,'4':60}


'''
spots 风景区
restaurants 餐厅
restaurantsAreas 餐厅所在区域

usrcity 用户来源地 0~684
usrcount 游客数量
avgAge 平均年龄
preference 偏好

time 时间
'''
spots = pd.read_csv("./spots.csv")           	
restaurants = pd.read_csv("./meishi-jsonFile.csv")
restaurantsAreas = np.unique(restaurants['areaName'])
hotel = pd.read_csv("./hotel.csv")
relax = pd.read_csv('./xiuxianyule.csv')  
usrcity = pd.read_csv('./from(province).csv')

usrId = []
avgAge = []
time = []
usrcount = {'0':'单人','1':'两人','2':'3~5人','3':'10人左右','4':'30~50人左右'}
preference = {1:'挑战刺激',2:'轻松愉悦',3:'趣味游玩',4:'舒缓散心',5:'寓情于景'}
acceptablerange = ['0~10km', '10~20km', '20~40km', '40km以上']

#用户ID产生
def createRandomString(len):
    # print ('wet'.center(10,'*'))
    raw = ""
    range1 = range(58, 65) # between 0~9 and A~Z
    range2 = range(91, 97) # between A~Z and a~z

    i = 0
    while i < len:
        seed = random.randint(48, 122)
        if ((seed in range1) or (seed in range2)):
            continue;
        raw += chr(seed);
        i += 1
    return raw

import time,random
def generateTime(a1,a2):
    start=time.mktime(a1)    #生成开始时间戳
    end=time.mktime(a2)      #生成结束时间戳
    t=random.randint(start,end)    #在开始和结束时间戳中随机取出一个
    date_touple=time.localtime(t)          #将时间戳生成时间元组
    date=time.strftime("%Y-%m-%d",date_touple)  #将时间元组转成格式化字符串（1976-05-21）
    return date

#保存文件
def save_datas(datas, filename):
	with open(filename, 'a', encoding='GB18030', newline='') as c:
		fieldnames = ['usrID', 'time', 'source',  'usrcount', 'usrtype', 'avgprice','avgage', 'preference',\
                      'interestofspot', 'acceptablerange', \
                      'place1', 'place2', 'place3', 'place4', 'place5', 'place6', 'place7', 'place8']
		writer = csv.DictWriter(c, fieldnames=fieldnames)
		for data in datas:
			writer.writerow(data)

def random_index(rate):
    """随机变量的概率函数"""
    #
    # 参数rate为list<int>
    # 返回概率事件的下标索引
    start = 0
    index = 0
    randnum = random.randint(1, sum(rate))

    for index, scope in enumerate(rate):
        start += scope
        if randnum <= start:
            break
    return index

def selectrestaurants(spotvalue1, restaurants, avgpricevalue):
    '''
    靠近第一个景区的美食
    spotvalue1 == 4-8 10-11 莫干山风景区 洋家乐
    spotvalue1 == 2-3 9 莫干山 洋家乐
    spotvalue1 == 1    三合乡13km 19min, 
    spotvalue1 == 12    新市镇 河滨公园 1.3km
    spotvalue1 == 0    春晖公园11.2km 德清县10.8km 德清县中心城区10km 汇丰广场10.7km 开发区11km 康乐小区11.9km 
                        蓝色港湾9.8km  科技新城11km 18min 群安小区 12.2km 20min 私营城14km 23min 沃尔玛12.6km 19min
                        武康镇10.4km 17min 营盘小区11km 17min 永安小区11.4km 18min 余英坊12km 18min 下渚湖
                        雷甸镇 12.7km 18min
                        乾元镇 6.2km 10min 
                        三合乡 7.9km 11min
                        禹越镇 29.1km 38min
                        河滨公园 28.1km 37min

    '''
    restaurantareaName = np.array(restaurants['areaName'])
    restaurantindex = []
    if spotvalue1 == 12:
        restaurantindex1 = np.argwhere(restaurantareaName=='新市镇')
        restaurantindex2 = np.argwhere(restaurantareaName=='河滨公园')
        restaurantindex = np.append(restaurantindex1,restaurantindex2)
    elif spotvalue1 == 1:
        restaurantindex = []
        restaurantindex1 = np.argwhere(restaurantareaName=='三合乡')
        restaurantindex = np.append(restaurantindex,restaurantindex1)
    elif spotvalue1 == 2 or spotvalue1 == 3 or spotvalue1 == 9:
        restaurantindex1 = np.argwhere( restaurantareaName=='莫干山')
        restaurantindex2 = np.argwhere( restaurantareaName=='洋家乐')
        restaurantindex = np.append(restaurantindex1,restaurantindex2)
    elif (spotvalue1 >= 4 and spotvalue1 <= 8) or (spotvalue1 >= 10 and spotvalue1 <= 11):
        restaurantindex1 = np.argwhere( restaurantareaName=='莫干山风景区')
        restaurantindex2 = np.argwhere( restaurantareaName=='洋家乐')
        restaurantindex = np.append(restaurantindex1,restaurantindex2)
    elif spotvalue1 == 0:
        areaNAMEs = ['春晖公园', '德清县', '德清县中心城区', '汇丰广场', '开发区', '康乐小区', 
                    '蓝色港湾', '科技新城', '群安小区', '私营城', '沃尔玛', '武康镇', '营盘小区',
                    '永安小区', '余英坊', '下渚湖', '雷甸镇', '乾元镇', '三合乡']
        restaurantindex = [ ]
        for areaNAME in areaNAMEs:
            restaurantindex1 = np.argwhere( restaurantareaName == areaNAME)
            restaurantindex = np.append(restaurantindex, restaurantindex1)
    '''
    根据平均消费，决定饭店地址
    '''
    if avgpricevalue <= 2000:
        place2index1 = list(restaurants['avgPrice'][restaurants['avgPrice']<50].index)
    elif avgpricevalue <= 3500:
        place2index1 = list(restaurants['avgPrice'][restaurants['avgPrice']<100].index)
    else:
        place2index1 = list(restaurants['avgPrice'][restaurants['avgPrice']>100].index)
    place2index = list(set(restaurantindex).intersection(set(place2index1)))
        # print(len(place2index1), len(restaurantindex), len(place2index))
    try:
        place2value = choice(place2index)
    except:
        place2value = choice(restaurantindex)
    return place2value

def selectrelax(spotvalue1, relax, avgpricevalue):
    '''
    靠近第一个景区的美食
    spotvalue1 == 4-8 10-11 莫干山风景区 洋家乐
    spotvalue1 == 2-3 9     莫干山 洋家乐
    spotvalue1 == 1         三合乡13km 19min, 
    spotvalue1 == 12        新市镇 河滨公园 1.3km
    spotvalue1 == 0         春晖公园11.2km 德清县10.8km 德清县中心城区10km 汇丰广场10.7km 开发区11km 康乐小区11.9km 
                            蓝色港湾9.8km  科技新城11km 18min 群安小区 12.2km 20min 私营城14km 23min 沃尔玛12.6km 19min
                            武康镇10.4km 17min 营盘小区11km 17min 永安小区11.4km 18min 余英坊12km 18min 下渚湖
                            雷甸镇 12.7km 18min
                            乾元镇 6.2km 10min 
                            三合乡 7.9km 11min
                            禹越镇 29.1km 38min
                            河滨公园 28.1km 37min

    '''
    relaxareaName = np.array(relax['area'])
    relaxindex = []
    if spotvalue1 == 12:
        relaxindex1 = np.argwhere(relaxareaName=='新市镇')
        relaxindex2 = np.argwhere(relaxareaName=='河滨公园')
        relaxindex = np.append(relaxindex1,relaxindex2)
    elif spotvalue1 == 1:
        return random.randrange(0,55,1)
    elif spotvalue1 >= 2 and spotvalue1 <= 11:
        relaxindex = []
        relaxindex1 = np.argwhere( relaxareaName=='莫干山')
        relaxindex = np.append(relaxindex,relaxindex1)
    elif spotvalue1 == 0:
        areaNAMEs = ['德清', '德清县中心城区', '汇丰广场', '开发区',
                    '科技新城', '群安小区', '私营城', '沃尔玛', '武康镇', '营盘小区',
                    '永安小区', '余英坊']
        relaxindex = [ ]
        for areaNAME in areaNAMEs:
            relaxindex1 = np.argwhere( relaxareaName == areaNAME)
            relaxindex = np.append(relaxindex, relaxindex1)
    '''
    根据平均消费，决定饭店地址
    '''
    if avgpricevalue <= 2000:
        place2index1 = list(relax['avgprice'][relax['avgprice']<100].index)
    elif avgpricevalue <= 3500:
        place2index1 = list(relax['avgprice'][relax['avgprice']<150].index)
    else:
        place2index1 = list(relax['avgprice'][relax['avgprice']>100].index)
    place2index = list(set(relaxindex).intersection(set(place2index1)))
        # print(len(place2index1), len(relaxindex), len(place2index))
    try:
        place2value = choice(place2index)
    except:
        place2value = choice(relaxindex)
    return place2value

def selectplace3(distance,spots,spotvalue1,rangevalue):
    disfrom1 = np.array(distance[spots['景点'][spotvalue1]])
    if rangevalue == 0:
        spot2index = np.argwhere(disfrom1 < 10)
    elif rangevalue == 1:
        spot2index = np.argwhere(disfrom1 < 20)
    elif rangevalue == 2:
        spot2index = np.argwhere(disfrom1 < 40)
    elif rangevalue == 3:
        spot2index = np.argwhere(disfrom1 < 100)
    
    spotvalue2 = choice(spot2index)[0]
    # print(disfrom1, rangevalue, spot2index, spotvalue2, spotvalue1)
    return spotvalue2

# '''
# 下渚湖国家湿地
# 东明山森林公园
# 蚕乐谷
# 庾村
# 旭光台
# 松月庐
# 芦花荡公园
# 剑池
# 莫干山大坑景区
# 裸心堡
# 三九坞
# 德清后坞村景区
# 新市古镇
# '''
# def selectplace3(distance,spots,spotvalue1,rangevalue):
#     spotvalue2 = []
#     if spotvalue1 >= 0 and spotvalue1 <= 12:
#         spotvalue2 = spotvalue1 + 1        
#     elif spotvalue1 == 13:
#         spotvalue2 = 1
#     return spotvalue2

def parse_datas(a1,a2):
    data = {}
    '''
    用户id随机生成
    '''
    data['usrID'] = createRandomString(20)

    '''
    时间按30%的比例模拟重点节日出行
    '''
    data['time'] = generateTime(a1,a2)

    '''
    685个来源地，来源地精确到市级，来源地随机生成
    '''
    sourcevalue = random.randrange(0,685,1)
    data['source'] = usrcity['省级地区'][sourcevalue]
    '''
    用户人数和类型
    1    ~ 单人任意游
    2    ~ 友人、情侣、亲情
    3-5  ~ 好友、亲属
    10   ~ 小团体团建
    30   ~ 大团体团建
    '''
    usrcountvalue = random.randrange(0,5,1)
    data['usrcount'] = usrcount[str(usrcountvalue)]
    usrtype = {'1':'单人任意游','2':'好友','3':'亲属','4':'情侣','5':'小团体团建','6':'大团体团建'}
    if usrcountvalue == 0:
        data['usrtype'] = usrtype['1']
        usrnum = 1
    elif usrcountvalue == 1:
        usrnum = random.randrange(2,5,1)
        data['usrtype'] = usrtype[str(usrnum)]
    elif usrcountvalue == 2:
        usrnum = random.randrange(2,4,1)
        data['usrtype'] = usrtype[str(usrnum)]
    elif usrcountvalue == 3:
        data['usrtype'] = usrtype['5']
        usrnum = 5
    elif usrcountvalue == 4:
        data['usrtype'] = usrtype['6']
        usrnum = 6
    '''
    平均消费能力
    '''
    data['avgprice'] = random.randrange(1000,5000,33)
    avgpricevalue = data['avgprice']
    '''
    2018年国内旅游用户年龄占比
    19岁以下    12.8%
    19~25岁     23.2%
    26~35岁     35.4%
    36~45岁     13.7%
    46~55岁     7.9%
    55岁以上    7%
    '''
    age = [[15,20],[20,26],[26,36],[36,46],[46,56],[56,70]]
    agerate = [13, 23, 35, 14, 8, 7]
    ageindex = random_index(agerate)
    data['avgage'] = random.randrange(age[ageindex][0],age[ageindex][1],1)
    avgagevalue = data['avgage']

    '''
    preference
                {1:'挑战刺激',2:'轻松愉悦',3:'趣味游玩',4:'舒缓散心',5:'寓情于景'}
    
    19岁以下        40           20         15          15           10
    19~25岁         40           20         15          15           10
    26~35岁         25           30         15          15           15
    36~45岁         15           30         15          30           10
    46~55岁         5            40         15          20           20
    55岁以上        5            35         10          25           25
    '''
    if ageindex == 0 or ageindex == 1:
        preferencerate = [40,20,15,15,10]
    elif ageindex == 2:
        preferencerate = [25,30,15,15,15]
    elif ageindex == 3:
        preferencerate = [15,30,15,30,10]
    elif ageindex == 4:
        preferencerate = [5, 40,15,20,20]
    elif ageindex == 5:
        preferencerate = [5, 35,10,25,25]        
    preferencevalue = random_index(preferencerate)+1
    data['preference'] = preference[preferencevalue]
    '''
    感兴趣的景点随机选择
    '''
    interestofspot = random.randrange(0,13,1)
    data['interestofspot'] = spots['景点'][interestofspot]
    '''
    可接受的移动范围
    usrcountvalue  ageindex      {0~10km, 10~20km, 20~40km, 40km以上}
    0,1,2           0,1,2          25       25      25      25 
    0,1,2           3,4,5          40       30      20      10
    3,4             0,1,2          45       30      20      5
    3,4             3,4,5          75       15      5      5
    usrcountvalue {'0':'单人','1':'两人','2':'3~5人','3':'10人左右','4':'30~50人左右'}
    ageindex {19岁以下, 19~25岁, 26~35岁, 36~45岁, 46~55岁, 55岁以上}
    '''
    if usrcountvalue < 3 and ageindex < 3:
        rangerate = [25, 25, 25, 25]
    elif usrcountvalue < 3 and ageindex >= 3:
        rangerate = [40, 30, 20, 10]
    elif usrcountvalue >= 3 and ageindex < 3:
        rangerate = [45, 30, 20, 5]
    elif usrcountvalue >= 3 and ageindex >= 3:
        rangerate = [75, 15, 5, 5]
    rangevalue = random_index(rangerate)
    data['acceptablerange'] = acceptablerange[rangevalue]
    
    '''
    感兴趣景区第一个参观
    '''
    spotvalue1 = interestofspot
    data['place1'] = spots['景点'][spotvalue1]
    '''
    第一天餐厅
    '''
    if spotvalue1 == 13:
        place2value = selectrestaurants(0, restaurants, avgpricevalue)
    else:
        place2value = selectrestaurants(spotvalue1, restaurants, avgpricevalue)
    data['place2'] = restaurants['name'][place2value]
    '''
    结合第一个景点和可接受距离，找到第二个景点
    acceptablerange = ['0~10km', '10~20km', '20~40km', '40km以上']
    ''' 
    spotvalue2 = selectplace3(distance,spots,spotvalue1,rangevalue)
    limit = 5
    while spotvalue2 == spotvalue1 and limit < 0:
        spotvalue2 = selectplace3(distance,spots,spotvalue1,rangevalue)
        limit = limit - 1
    while spotvalue2 == spotvalue1:
        spotvalue2 = random.randrange(0,13,1)
    if spotvalue2 == 13:
        data['place3'] = spots['景点'][0]
    else:
        data['place3'] = spots['景点'][spotvalue2]
    '''
    第一天住宿酒店
    '''
    place4value = random.randrange(0,1057,1)
    data['place4'] = hotel['name'][place4value]
    '''
    第二天景点
    '''
    spotvalue3 = selectplace3(distance,spots,spotvalue2,rangevalue)
    limit = 5
    while (spotvalue3 == spotvalue1 or spotvalue3 == spotvalue2) and (limit < 0):
        spotvalue3 = selectplace3(distance,spots,spotvalue2,rangevalue)
        limit = limit - 1
    while spotvalue3 == spotvalue1 or spotvalue3 == spotvalue2:
        spotvalue3 = random.randrange(0,13,1)
    if spotvalue3 == 13:
        data['place5'] = spots['景点'][0]
    else:
        data['place5'] = spots['景点'][spotvalue3]
    '''
    第二天餐厅
    '''
    if spotvalue3 == 13:
        place6value = selectrestaurants(0, restaurants, avgpricevalue)
    else:
        place6value = selectrestaurants(spotvalue3, restaurants, avgpricevalue)
    data['place6'] = restaurants['name'][place6value]
    # place6value = random.randrange(0,3268,1)
    # data['place6'] = restaurants['name'][place6value]
    '''
    休闲娱乐场所
    '''
    if spotvalue3 == 13:
        place7value = selectrelax(0, relax, avgpricevalue)
    else:
        place7value = selectrelax(spotvalue3, relax, avgpricevalue)
    data['place7'] = relax['name'][place7value]

    '''
    酒店
    '''
    place8value = random.randrange(0,1057,1)
    data['place8'] = hotel['name'][place8value]

    number = {'time':data['time'], 'source':sourcevalue, 'avgprice':avgpricevalue, 'usrcount':usrcountvalue, \
              'usrtype':usrnum, 'avgage':avgagevalue, 'preference':preferencevalue, 'interestofspot':interestofspot, \
              'acceptablerange':rangevalue, \
              'place1':spotvalue1, 'place2':place2value, 'place3':spotvalue2, \
              'place4':place4value, 'place5':spotvalue3, 'place6':place6value, 'place7':place7value, \
              'place8':place8value}
    
    
    return data, number
    # yield data
    # yield number

def back(data):
    yield data

def dateParameter(i):
    '''
        样本共计12407样本
        七大重点节日占比30% 3722个样本

        元旦    2019.1.1                138 * 2 = 276
        春节    2019.2.4~2019.2.11      415 * 2 = c830
        清明    2019.4.5~2019.4.7       112 * 2 = 224
        五一    2019.5.1~2019.5.4       195 * 2 = 390
        端午    2019.6.7~2019.7.9       96  * 2 = 192
        中秋    2019.9.13~2019.9.15     105 * 2 = 210
        国庆    2019.10.1~2019.10.7     800 * 2 = 1600
    '''
    if i < 276:
        a1=(2019, 1,  1,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 1,  2,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276 and i < 276+830:
        a1=(2019, 2,  4,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 2,  12, 23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276+830 and i < 276+830+224:
        a1=(2019, 4,  5,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 4,  7,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276+830+224 and i < 276+830+224+390:
        a1=(2019, 5,  1,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 5,  4,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276+830+224+390 and i < 276+830+224+390+192:
        a1=(2019, 6,  7,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 7,  9,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276+830+224+390+192 and i < 276+830+224+390+192+210:
        a1=(2019, 9,  13,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 9,  15,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组
    elif i >= 276+830+224+390+192+210 and i < 276+830+224+390+192+210+1600:
        a1=(2019, 10,  1,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 10,  7,  23, 59, 59, 0, 0, 0)    #设置结束日期时间元组 
    elif i >= 276+830+224+390+192+210+1600:
        a1=(2019, 1,  1,  0,  0,  0,  0, 0, 0)    #设置开始日期时间元组
        a2=(2019, 12, 31, 23, 59, 59, 0, 0, 0)    #设置结束日期时间元组   
    return a1, a2

if __name__ == '__main__':

    for i in range(12407):
        a1, a2 = dateParameter(i) 
        data, number = parse_datas(a1, a2)
        data = back(data)
        number = back(number)
        print(i, data)
        save_datas(data,'rount.csv')
        save_datas(number,'rountnumber.csv')